package com.ycy.chuwenuniapp.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycy.chuwenuniapp.common.Constant;
import com.ycy.chuwenuniapp.common.ResCodeEnum;
import com.ycy.chuwenuniapp.common.ResData;
import com.ycy.chuwenuniapp.dto.GoodsDetailDto;
import com.ycy.chuwenuniapp.dto.GoodsOutboundDto;
import com.ycy.chuwenuniapp.entity.*;
import com.ycy.chuwenuniapp.exception.CustomException;
import com.ycy.chuwenuniapp.mapper.IGoodsMapper;
import com.ycy.chuwenuniapp.vo.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

@Service
public class GoodsService extends ServiceImpl<IGoodsMapper, Goods> {
    @Resource
    private GoodsTypeService goodsTypeService;
    @Resource
    private GoodsSizeService goodsSizeService;
    @Resource
    private GoodsColorService goodsColorService;
    @Resource
    private GoodsCountService goodsCountService;
    
    //增加
    public ResData<String> addGoods(GoodsDetailDto dto, Boolean isAdd) {
        String typeId = dto.getTypeId();
        String name = dto.getName();
        Double price = dto.getPrice();
        if(StrUtil.isBlank(typeId)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"缺失商品类型id");
        if(StrUtil.isBlank(name)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"缺失商品名");
        if(price == null) throw new CustomException(ResCodeEnum.BAD_REQUEST,"缺失商品价格");

        //保存商品基本信息
        Goods entity = new Goods();
        BeanUtil.copyProperties(dto,entity);
        String goodsUuid = IdUtil.getSnowflakeNextIdStr();
        if(isAdd) entity.setId(goodsUuid);
        else entity.setId(dto.getId());
        boolean isSaveGoods = save(entity);
        if (!isSaveGoods) throw new CustomException(ResCodeEnum.SERVER_ERROR, "服务器错误,保存商品失败");


        List<GoodsOtherParamsVo> paramsList = dto.getParamsList();
        paramsList.forEach(item -> {
            GoodsSize goodsSize = new GoodsSize();
            goodsSize.setSize(item.getSize());
            String sizeUuid = IdUtil.getSnowflakeNextIdStr();

            if(isAdd) {
                goodsSize.setGoodsId(goodsUuid);
                goodsSize.setId(sizeUuid);
            }else {
                goodsSize.setGoodsId(dto.getId());
                goodsSize.setId(item.getSizeId());
            }
            boolean isSaveSize = goodsSizeService.saveGoodsSize(Constant.ADD, goodsSize);
            if (!isSaveSize) throw new CustomException(ResCodeEnum.SERVER_ERROR, "服务器错误,保存商品尺码失败");

            List<GoodsColorCountVo> colorCountList = item.getColorCountList();
            colorCountList.forEach(colorCountItem -> {
                GoodsColor goodsColor = new GoodsColor();
                goodsColor.setColor(colorCountItem.getColor());
                String colorUuid = IdUtil.getSnowflakeNextIdStr();
                if(isAdd) {
                    goodsColor.setId(colorUuid);
                    goodsColor.setSizeId(sizeUuid);
                }else {
                    goodsColor.setId(colorCountItem.getColorId());
                    goodsColor.setSizeId(item.getSizeId());
                }
                boolean isSaveColor = goodsColorService.saveGoodsColor(Constant.ADD, goodsColor);
                if (!isSaveColor) throw new CustomException(ResCodeEnum.SERVER_ERROR, "服务器错误,保存商品颜色失败");

                GoodsCount goodsCount = new GoodsCount();
                goodsCount.setCount(colorCountItem.getCount());
                if(isAdd) goodsCount.setColorId(colorUuid);
                else {
                    goodsCount.setId(colorCountItem.getCountId());
                    goodsCount.setColorId(colorCountItem.getColorId());
                }
                boolean isSaveCount = goodsCountService.saveGoodsCount(Constant.ADD, goodsCount);
                if (!isSaveCount) throw new CustomException(ResCodeEnum.SERVER_ERROR, "服务器错误,保存商品数量失败");
            });
        });

        if(isAdd) return ResData.success(goodsUuid,"保存成功");
        else return ResData.success(dto.getId(),"保存成功");
    }

    //修改(先删除，后增加，但各个id是不变的)
    public ResData<String> updateGoods(GoodsDetailDto dto) {
        Boolean isDelete = delete(dto.getId()).getData();
        if (!isDelete) throw new CustomException(ResCodeEnum.SERVER_ERROR, "服务器错误,修改商品信息时步骤一失败");
        return addGoods(dto, false);
    }

    //查询每种商品类型的数量
    public ResData<ArrayList<GoodsTypeCountVo>> findEveryTypeGoodsCount() {
        List<GoodsType> typeList = goodsTypeService.list();
        ArrayList<GoodsTypeCountVo> voList = new ArrayList<>();
        typeList.forEach(item -> {
            QueryWrapper<Goods> wrapper = new QueryWrapper<>();
            wrapper.eq("type_id", item.getId());
            GoodsTypeCountVo vo = new GoodsTypeCountVo();
            vo.setCount(count(wrapper));
            vo.setId(item.getId());
            vo.setName(item.getName());
            voList.add(vo);
        });
        return ResData.success(voList);
    }

    //查全部(不含商品详细信息)
    public ResData<List<GoodsVo>> findAll(String typeId, String name) {
        QueryWrapper<Goods> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("create_time");
        wrapper.like(StrUtil.isNotBlank(name),"name",name);
        wrapper.eq(StrUtil.isNotBlank(typeId),"type_id",typeId);
        List<Goods> goodsList = list(wrapper);

        return ResData.success(entityListToVoList(goodsList),"查询成功");
    }

    //查询单个详情,isOutbound可不传，默认为 false
    public ResData<GoodsDetailVo> findOneDetail(String goodsId,Boolean isOutbound) {
        if(StrUtil.isBlank(goodsId)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"缺失商品id");

        Goods goods = getById(goodsId);
        if(goods == null) throw new CustomException(ResCodeEnum.BAD_REQUEST,"该id的商品不存在");
        GoodsType goodsType = goodsTypeService.getById(goods.getTypeId());
        if(goodsType == null) throw new CustomException(ResCodeEnum.BAD_REQUEST,"该id的商品分类不存在");

        List<GoodsSize> goodsSizeList = goodsSizeService.findAll(goodsId, null);
        ArrayList<String> goodsSizeIdList = new ArrayList<>();
        ArrayList<GoodsOtherParamsVo> otherParamsVoList = new ArrayList<>();
        goodsSizeList.forEach(item -> {
            goodsSizeIdList.add(item.getId());
            GoodsOtherParamsVo otherParamsVo = new GoodsOtherParamsVo();
            otherParamsVo.setSizeId(item.getId());
            otherParamsVo.setSize(item.getSize());
            otherParamsVoList.add(otherParamsVo);
        });

        List<GoodsColor> goodsColorList = goodsColorService.findAllByGoodsSizeIds(goodsSizeIdList);
        ArrayList<String> goodsColorIdList = new ArrayList<>();
        goodsColorList.forEach(item -> goodsColorIdList.add(item.getId()));

        List<GoodsCount> goodsCountList = goodsCountService.findAllBySizeAndColorIds(goodsSizeIdList, goodsColorIdList);

        otherParamsVoList.forEach(item -> {
            ArrayList<GoodsColorCountVo> colorCountList = new ArrayList<>();
            for (GoodsColor goodsColor : goodsColorList) {
                if (item.getSizeId().equals(goodsColor.getSizeId())) {
                    GoodsColorCountVo colorCountVo = new GoodsColorCountVo();
                    colorCountVo.setColor(goodsColor.getColor());
                    colorCountVo.setColorId(goodsColor.getId());
                    for (GoodsCount goodsCount : goodsCountList) {
                        if (goodsColor.getId().equals(goodsCount.getColorId())) {
                            if(isOutbound != null && isOutbound) colorCountVo.setCount(0);
                            else colorCountVo.setCount(goodsCount.getCount());
                            colorCountVo.setStoreCount(goodsCount.getCount());
                            colorCountVo.setCountId(goodsCount.getId());
                            colorCountVo.setIsLack(goodsCount.getCount() == 0);
                            break;
                        }
                    }
                    colorCountList.add(colorCountVo);
                }
            }
            item.setColorCountList(colorCountList);
        });

        GoodsDetailVo goodsDetailVo = new GoodsDetailVo();
        BeanUtil.copyProperties(goods,goodsDetailVo);  //商品基本数据， 还有typeName,paramsList
        goodsDetailVo.setTypeName(goodsType.getName()); //商品类型名, 还有paramsList
        goodsDetailVo.setParamsList(otherParamsVoList);

        return ResData.success(goodsDetailVo);
    }

    //单个删除
    public ResData<Boolean> delete(String goodsId) {
        if(StrUtil.isBlank(goodsId)) throw new CustomException(ResCodeEnum.BAD_REQUEST,"缺失商品id");
        boolean isRemoveGoods = removeById(goodsId);
        if (!isRemoveGoods) throw new CustomException(ResCodeEnum.SERVER_ERROR, "服务器错误,删除商品失败");

        QueryWrapper<GoodsSize> sizeWrapper = new QueryWrapper<>();
        sizeWrapper.eq("goods_id",goodsId);
        sizeWrapper.select("id");
        List<GoodsSize> goodsSizeList = goodsSizeService.list(sizeWrapper);

        Boolean isRemoveSize = goodsSizeService.delete(goodsId);
        if (!isRemoveSize) throw new CustomException(ResCodeEnum.SERVER_ERROR, "服务器错误,删除商品尺码失败");
        LinkedList<String> sizeIdList = new LinkedList<>();
        goodsSizeList.forEach(item -> sizeIdList.addFirst(item.getId()));

        QueryWrapper<GoodsColor> colorWrapper = new QueryWrapper<>();
        colorWrapper.in("size_id",sizeIdList);
        colorWrapper.select("id");
        List<GoodsColor> goodsColorList = goodsColorService.list(colorWrapper);
        LinkedList<String> colorIdList = new LinkedList<>();
        goodsColorList.forEach(item -> colorIdList.addFirst(item.getId()));

        Boolean isRemoveColor = goodsColorService.delete(sizeIdList);
        if (!isRemoveColor) throw new CustomException(ResCodeEnum.SERVER_ERROR, "服务器错误,删除商品尺码失败");

        Boolean isRemoveCount = goodsCountService.delete(colorIdList);
        if (!isRemoveCount) throw new CustomException(ResCodeEnum.SERVER_ERROR, "服务器错误,删除商品尺码失败");

        return ResData.success(true,"删除成功");
    }

    //商品出库
    public ResData<Boolean> outbound(List<GoodsOutboundDto> dtoList) {
        LinkedList<String> countIdList = new LinkedList<>();
        dtoList.forEach(item -> countIdList.addFirst(item.getCountId()));
        List<GoodsCount> countList = goodsCountService.findAllByIds(countIdList);
        if(countList.size() != dtoList.size()) throw new CustomException(ResCodeEnum.BAD_REQUEST, "有商品数量id错误");

        LinkedList<GoodsCount> outboundList = new LinkedList<>();
        countList.forEach(item -> {
            Integer countNum = item.getCount();
            for (GoodsOutboundDto dto: dtoList) {
                if(dto.getCountId().equals(item.getId())) {
                    Integer outboundCount = dto.getCount();
                    if(countNum >= outboundCount) {
                        item.setCount(countNum - outboundCount);
                        outboundList.addFirst(item);
                    }else throw new CustomException(ResCodeEnum.BAD_REQUEST, "有商品出库数量超过库存数");
                }
            }
        });
        boolean isUpdate = goodsCountService.updateBatchById(outboundList);
        if(isUpdate) return ResData.success(true, "出库成功");
        else return ResData.fail(true, "服务器错误,出库失败");
    }

    //查询缺货(数量为0的商品)信息
    public ResData<List<GoodsVo>> findAllLackGoods(String typeId, String name) {
        //查到数量为0的emptyCountList
        List<GoodsCount> emptyCountList = goodsCountService.findAllEmptyCount();
        if(emptyCountList.size() == 0) return ResData.success(new ArrayList<>());
        ArrayList<String> colorIdList = new ArrayList<>();
        emptyCountList.forEach(item -> colorIdList.add(item.getColorId()));

        //根据emptyCountList查到对应的colorList
        List<GoodsColor> colorList = goodsColorService.findAllByIds(colorIdList);
        ArrayList<String> sizeIdList = new ArrayList<>();
        colorList.forEach(item -> sizeIdList.add(item.getSizeId()));

        //根据emptyCountList查到对应colorList的sizeList
        List<GoodsSize> sizeList = goodsSizeService.findAllByIds(sizeIdList);

        //根据emptyCountList查到的sizeList，得到goodsList
        ArrayList<String> goodsIdList = new ArrayList<>();
        sizeList.forEach(item -> goodsIdList.add(item.getGoodsId()));

        QueryWrapper<Goods> wrapper = new QueryWrapper<>();
        wrapper.in("id",goodsIdList);
        wrapper.like(StrUtil.isNotBlank(name),"name",name);
        wrapper.eq(StrUtil.isNotBlank(typeId),"type_id",typeId);
        List<Goods> goodsList = list(wrapper);

        return ResData.success(entityListToVoList(goodsList),"查询成功");
    }

    private List<GoodsVo> entityListToVoList(List<Goods> goodsList) {
        ArrayList<GoodsVo> voList = new ArrayList<>();
        goodsList.forEach(item -> {
            GoodsVo vo = new GoodsVo();
            BeanUtil.copyProperties(item,vo);
            voList.add(vo);
        });
        return voList;
    }
}
